package com.kx.yooli.kx.wechat.service.disruptor;

import com.kx.yooli.kx.wechat.entity.disrutor.MessageModel;
import com.kx.yooli.kx.wechat.service.IDisruptorMqService;
import com.lmax.disruptor.RingBuffer;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Service;

/**
 * @author john_sqwen-childe.wen
 * @date 2024/3/28
 * @PROJECT_NAME wechat
 * @description create DisruptorMqServiceImpl by john_sqwen
 * and DisruptorMqServiceImpl value is
 */
@Service
public class DisruptorMqServiceImpl implements IDisruptorMqService {
    private final Logger log = LoggerFactory.getLogger(DisruptorMqServiceImpl.class);
    @Resource
    private RingBuffer<MessageModel> messageModelRingBuffer;
    @Override
    public void sendMessageMq(String message) {
        log.info("record the message: {}",message);
        //Get the index of the next Event slot
        long sequence = messageModelRingBuffer.next();
        try {
            //Fill the Event with data
            MessageModel event = messageModelRingBuffer.get(sequence);
            event.setMessage(message);
            //log.info("往消息队列中添加消息：{}", event);
            log.info("Add messages to the message queue：{},traceId {}", event, MDC.get("traceId"));
        }catch (Exception e){
            log.error("failed to add event to messageModelRingBuffer for : e = {},{}",e,e.getMessage());
            e.printStackTrace();
        }finally {
            //Publish an Event, activate observers to consume, and pass the sequence to the changing consumers
            //Note that the final publish method must be placed in finally to ensure that it must be called; If the sequence of a request is not submitted,
            // it will block subsequent publishing operations or other producers
            messageModelRingBuffer.publish(sequence);
        }
    }
}
